import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import '../models/response_model.dart';
import '../providers/auth_provider.dart';

typedef ApiJsonMap = Map<String, dynamic>;

/// API服务类，封装所有网络请求和认证处理逻辑
class ApiService {
  final http.Client client;
  final Ref ref;
  static const String baseUrl = 'http://10.0.2.2:3000/api';

  ApiService(this.ref, {http.Client? client})
      : client = client ?? http.Client();

  /// 刷新token的方法
  Future<bool> _refreshToken() async {
    try {
      final authState = ref.read(authStateProvider);
      if (authState.value?.refreshToken == null) return false;

      final response = await client.post(
        Uri.parse('$baseUrl/auth/refresh'),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'refreshToken': authState.value!.refreshToken}),
      );

      if (response.statusCode == 200) {
        try {
          final data = jsonDecode(response.body);
          // 处理统一响应格式
          final apiResponse = ApiResponse.fromJson(data, (json) => json);
          if (apiResponse.isSuccess && apiResponse.data != null) {
            final tokenData = apiResponse.data!;
            if (tokenData.containsKey('accessToken') &&
                tokenData.containsKey('refreshToken')) {
              await ref.read(authStateProvider.notifier).updateTokens(
                    accessToken: tokenData['accessToken'],
                    refreshToken: tokenData['refreshToken'],
                  );
              return true;
            }
          }
        } catch (e) {
          debugPrint('解析token响应失败: $e');
        }
      }
      return false;
    } catch (e) {
      debugPrint('刷新token失败: $e');
      return false;
    }
  }

  /// 发送HTTP请求的私有辅助方法
  Future<http.Response> _sendRequest(
    String endpoint,
    String method,
    Map<String, dynamic>? body,
    Map<String, String>? headers,
    bool requiresAuth,
  ) async {
    final uri = Uri.parse('$baseUrl$endpoint');
    final authState = ref.read(authStateProvider);
    // 构建请求头
    final requestHeaders = {
      'Content-Type': 'application/json',
      if (requiresAuth && authState.value?.accessToken != null)
        'x-access-token': authState.value!.accessToken!,
      ...headers ?? {},
    };

    // 发送请求
    try {
      switch (method.toUpperCase()) {
        case 'GET':
          return await client.get(uri, headers: requestHeaders);
        case 'POST':
          return await client.post(
            uri,
            headers: requestHeaders,
            body: body != null ? jsonEncode(body) : null,
          );
        case 'PUT':
          return await client.put(
            uri,
            headers: requestHeaders,
            body: body != null ? jsonEncode(body) : null,
          );
        case 'DELETE':
          return await client.delete(uri, headers: requestHeaders);
        default:
          throw Exception('不支持的请求方法: $method');
      }
    } catch (e) {
      throw Exception('网络请求失败: $e');
    }
  }

  /// 处理认证和响应的私有辅助方法
  Future<T> _processResponse<T>(
    http.Response response,
    bool requiresAuth,
    T Function(Map<String, dynamic>) createResponse,
    Future<T> Function() retryRequest,
  ) async {
    final authState = ref.read(authStateProvider);

    // 处理401错误（token过期）
    if (response.statusCode == 401 &&
        requiresAuth &&
        authState.value?.accessToken != null) {
      // 尝试刷新token
      final refreshSuccess = await _refreshToken();
      if (refreshSuccess) {
        // 刷新成功后重试请求
        return retryRequest();
      } else {
        // 刷新失败，清除认证状态
        ref.read(authStateProvider.notifier).logout();
        String errorMessage = _extractErrorMessage(response, '认证已过期，请重新登录');
        throw Exception(errorMessage);
      }
    }

    // 处理其他HTTP错误状态码
    if (response.statusCode < 200 || response.statusCode >= 300) {
      String errorMessage =
          _extractErrorMessage(response, '请求失败 (${response.statusCode})');
      throw Exception(errorMessage);
    }

    // 解析响应
    try {
      debugPrint("[request][response]: ${response.body}");
      final responseData = jsonDecode(response.body) as Map<String, dynamic>;
      final apiResponse = createResponse(responseData);

      // 如果API返回错误但HTTP状态码是200，抛出异常
      if (apiResponse is ApiResponse && !apiResponse.isSuccess) {
        throw Exception(
            apiResponse.message.isNotEmpty ? apiResponse.message : '请求失败');
      }

      return apiResponse;
    } catch (e) {
      if (e is Exception) {
        rethrow;
      }
      throw Exception('解析响应失败: $e');
    }
  }

  /// 从响应中提取错误信息的辅助方法
  String _extractErrorMessage(http.Response response, String defaultMessage) {
    try {
      final responseData = jsonDecode(response.body) as Map<String, dynamic>;
      // 尝试从不同的字段获取错误信息
      if (responseData.containsKey('message') &&
          responseData['message'] is String) {
        return responseData['message'] as String;
      }
      if (responseData.containsKey('error') &&
          responseData['error'] is String) {
        return responseData['error'] as String;
      }
      if (responseData.containsKey('msg') && responseData['msg'] is String) {
        return responseData['msg'] as String;
      }
      // 对于404错误，提供更具体的信息
      if (response.statusCode == 404) {
        return '请求的资源不存在';
      }
    } catch (e) {
      // 如果解析失败，使用默认消息
      debugPrint('提取错误信息失败: $e');
    }
    return defaultMessage;
  }

  /// 通用请求方法，支持泛型响应
  Future<ApiResponse<T>> request<T>(
      String endpoint, T Function(dynamic) fromJsonT,
      {String method = 'GET',
      Map<String, dynamic>? body,
      Map<String, String>? headers,
      bool requiresAuth = true}) async {
    // 发送请求
    final response =
        await _sendRequest(endpoint, method, body, headers, requiresAuth);

    // 处理响应
    return _processResponse<ApiResponse<T>>(
      response,
      requiresAuth,
      (data) => ApiResponse<T>.fromJson(data, fromJsonT),
      () => request(endpoint, fromJsonT,
          method: method,
          body: body,
          headers: headers,
          requiresAuth: requiresAuth),
    );
  }

  /// 列表请求方法
  Future<ApiResponse<List<T>>> requestList<T>(
      String endpoint, T Function(dynamic) fromJsonT,
      {String method = 'GET',
      Map<String, dynamic>? body,
      Map<String, String>? headers,
      bool requiresAuth = true}) async {
    // 发送请求
    final response =
        await _sendRequest(endpoint, method, body, headers, requiresAuth);

    // 处理响应
    return _processResponse<ApiResponse<List<T>>>(
      response,
      requiresAuth,
      (data) {
        // 手动构建ApiResponse对象
        final listData = data['data'] as List?;
        final message = data['message'] as String? ?? '';
        final code = data['code'] as int? ?? 0;

        List<T> items = [];
        if (listData != null) {
          items = listData.map((item) => fromJsonT(item)).toList();
        }

        return ApiResponse<List<T>>(
          code: code,
          message: message,
          data: items,
        );
      },
      () => requestList(endpoint, fromJsonT,
          method: method,
          body: body,
          headers: headers,
          requiresAuth: requiresAuth),
    );
  }

  /// GET请求快捷方法
  Future<ApiResponse<T>> get<T>(String endpoint, T Function(dynamic) fromJsonT,
          {Map<String, String>? headers, bool requiresAuth = true}) =>
      request(endpoint, fromJsonT,
          method: 'GET', headers: headers, requiresAuth: requiresAuth);

  /// POST请求快捷方法
  Future<ApiResponse<T>> post<T>(String endpoint, T Function(dynamic) fromJsonT,
          {Map<String, dynamic>? body,
          Map<String, String>? headers,
          bool requiresAuth = true}) =>
      request(endpoint, fromJsonT,
          method: 'POST',
          body: body,
          headers: headers,
          requiresAuth: requiresAuth);

  /// PUT请求快捷方法
  Future<ApiResponse<T>> put<T>(String endpoint, T Function(dynamic) fromJsonT,
          {Map<String, dynamic>? body,
          Map<String, String>? headers,
          bool requiresAuth = true}) =>
      request(endpoint, fromJsonT,
          method: 'PUT',
          body: body,
          headers: headers,
          requiresAuth: requiresAuth);

  /// DELETE请求快捷方法
  Future<ApiResponse<T>> delete<T>(
          String endpoint, T Function(dynamic) fromJsonT,
          {Map<String, String>? headers, bool requiresAuth = true}) =>
      request(endpoint, fromJsonT,
          method: 'DELETE', headers: headers, requiresAuth: requiresAuth);

  /// GET列表请求快捷方法
  Future<ApiResponse<List<T>>> getList<T>(
          String endpoint, T Function(dynamic) fromJsonT,
          {Map<String, String>? headers, bool requiresAuth = true}) =>
      requestList(endpoint, fromJsonT,
          method: 'GET', headers: headers, requiresAuth: requiresAuth);
}

/// API服务的Provider
final apiServiceProvider = Provider<ApiService>((ref) {
  return ApiService(ref);
});
